/**
 * 处理仿问日志的FILTER
 */
package cn.antia.cep.common;

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

import cn.antia.cep.busi.DbHibernateService;
import cn.antia.cep.db.hibernate.bean.*;
import cn.antia.cep.ip.Utils;

/**
 * @author sunkeei
 * @date Mar 7, 2007
 * @version 0.1
 */
public class VisitFilter implements Filter {
	private String cannot;

	public void destroy() {
	}

	public void doFilter(ServletRequest request1, ServletResponse response1,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest)request1;
		HttpServletResponse response = (HttpServletResponse)response1;
		//session id
		String sessionId = request.getSession().getId();
		//上下文
		ServletContext context = request.getSession().getServletContext();
		//仿问记录
		HashMap usermap = (HashMap)context.getAttribute(SessionConst.USER_MAP);
		if(usermap == null){
			return;
		}
		VisitLog log = (VisitLog)usermap.get(sessionId);
		if(log == null){
			AntiaLog.error("出现程序错误！在仿问日志的FILTER中取得的SESSIOID不能在SERVLETCONTEXT中找到相应的仿问记录！");
			chain.doFilter(request,response);
			return;
		}
		//如果用户状态还没有定义－－定义
		String ip=request.getRemoteAddr();
		if(log.getUserType().intValue() == DBFlag.VISIT_LOG_USER_UNDEFINED){
			log.setIp(ip);
			log.setIpArea(Utils.getAddress(ip));
			log.setRemoteUser(request.getRemoteUser());
			log.setUserType(new Integer(DBFlag.VISIT_LOG_USER_UNREGISTERED));
			log.setClickTimes(new Integer(1));
			AntiaLog.info(new StringBuffer("用户").append(log.getIp()).append("登录。").toString());
		}else{
			//否则，点击量加一
			log.setClickTimes(new Integer(log.getClickTimes().intValue() + 1));
		}
		//判断是否有仿问权限
		Privilege privilege = (Privilege)request.getSession().getAttribute(SessionConst.PRIVILEGE);
		boolean hasRight = false;	//是否有管理员权限
		if(privilege != null && privilege.getRoles() != null){
			List roles = privilege.getRoles();
			for(int i = 0;i<roles.size();i++){
				Role role = (Role)roles.get(i);
				if(role.getId().intValue() == DBFlag.ROLE_SUPER_MANAGER || role.getId().intValue() == DBFlag.ROLE_NORMAL_MANAGER){
					hasRight = true;
					break;
				}
			}
		}
		String tagUri = request.getRequestURI();
		String[] cannots = cannot.split(";");
		for(int i = 0;i<cannots.length;i++){
			String not = cannots[i];
			//如果包含非法仿问的内容
			if(!hasRight && tagUri.indexOf(not) > -1){
				request.setAttribute("message", "非法操作，请确认您具体相关的操作权限。");
				AntiaLog.warn(new StringBuffer("用户 ").append(log.getIp()).append(" 企图仿问").append(tagUri).toString());
				addVisitErrorLog(tagUri,log.getIp(),request);
	            javax.servlet.RequestDispatcher rd;
	            rd = request.getRequestDispatcher("/user/logon.jsp");
	            rd.forward(request, response);
	            return;
			}
		}
		chain.doFilter(request,response);
	}

	public void init(FilterConfig config) throws ServletException {
		cannot = config.getInitParameter("cannot");
		AntiaLog.info("仿问日志的FILTER开始初始化....");
	}

	/*
	 *非法操作内容加入到数据库中保存
	 * path 企图访问路径
	 * ip 访问者IP 
	 */
	private void addVisitErrorLog(String path,String ip,HttpServletRequest request){
		VisitError errorLog=new VisitError();
		errorLog.setPath(path);
		errorLog.setIp(ip);
		errorLog.setTime(new Date());
		HttpSession session=request.getSession();		
		Privilege privilege=(Privilege)session.getAttribute("privilege");
		if(privilege != null){
			User user=privilege.getUser();
			if(user!=null){
				errorLog.setUserId(user.getId());
				errorLog.setUserName(user.getName());
				errorLog.setUserNickName(user.getNickname());
			}
		}
		//保存
		DbHibernateService service = (DbHibernateService)ContextBean.getBean("dbHibernateService");
		try {
			service.create(errorLog);
		} catch (AntiaException e) {	
			if(privilege != null){
				User user=privilege.getUser();
				if(user!=null){
					AntiaLog.info(new StringBuffer("非法访问:地址").append(errorLog.getPath()).append("ip").append(errorLog.getIp()).append(" :会员").append(user.getNickname()).toString());
				}
			}else{			
				AntiaLog.info(new StringBuffer("非法访问:地址").append(errorLog.getPath()).append("ip").append(errorLog.getIp()).toString());
			}
		}		
	}
}
